package com.koron.order.overhaul.notified;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.koron.bean.system.staff.po.AppUserPo;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.message.MessageUtil;
import com.koron.order.common.bean.base.OrderType;
import com.koron.order.common.bean.po.OrderDispatch;
import com.koron.order.common.bean.po.OrderDispatchWorker;
import com.koron.order.common.bean.po.OrderWorkDeptPo;
import com.koron.order.common.service.OrderDispatchService;
import com.koron.order.common.service.OrderDispatchTeamService;
import com.koron.order.common.service.OrderDispatchWorkerService;
import com.koron.order.common.service.OrderWorkDeptService;
import com.koron.order.overhaul.bean.convertor.OverhaulOrderConvertor;
import com.koron.order.overhaul.bean.entity.OverhaulOrderBean;
import com.koron.order.overhaul.bean.query.OverhaulOrderQuery;
import com.koron.order.overhaul.bean.vo.OrderDispatchTeamVO;
import com.koron.order.overhaul.bean.vo.OrderDispatchVO;
import com.koron.order.overhaul.service.OverhaulOrderService;
import com.koron.order.overhaul.utils.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author twcao
 * @title: OverhaulOrderDispatch
 * @projectName GDH_EAM_V2
 * @description: 大修工单-待派工
 * @date 2021/10/811:25
 */
@Slf4j
@Component
public class OverhaulOrderDispatch implements OverhaulOrderNotify<OrderDispatchVO> {

    @Autowired
    private OrderDispatchService dispatchService;

    @Autowired
    private OrderDispatchTeamService teamService;

    @Autowired
    private OrderDispatchWorkerService workerService;

    @Autowired
    private OverhaulOrderConvertor convertor;

    @Autowired
    private OverhaulOrderService orderService;

    @Autowired
    private OrderWorkDeptService workDeptService;

    @Autowired
    MessageUtil messageUtil;

    @Override
    public boolean execute(SessionFactory factory, OrderDispatchVO dispatch) {
        log.info("大修工单-待派工，vo = {}", JSON.toJSONString(dispatch));
        // 0、保存工单状态
        OverhaulOrderQuery query = new OverhaulOrderQuery();
        query.setId(dispatch.getOrderId());
        List<OverhaulOrderBean> orders = orderService.queryList(factory, query);
        Assert.notEmpty(orders, "工单不存在");
        OverhaulOrderBean order = orders.get(0);
        order.setStatus(dispatch.getStatus());
        orderService.saveOrUpdate(factory, order);
        // 1、派工信息
        Assert.notNull(dispatch, "派工信息不能为空");
        dispatch.setOrderType(OrderType.OVERHAUL);
        // 保存时会生成派工id
        dispatchService.insertOrUpdate(factory, dispatch);
        // 2、工作班组
        List<OrderDispatchTeamVO> teams = dispatch.getTeams();
        Stream.iterate(0, i -> i + 1).limit(teams.size()).forEach(i -> {
            OrderDispatchTeamVO team = teams.get(i);
            team.setId(StringUtils.isBlank(team.getId()) ? CodeTools.getCode32() : team.getId());
            team.setOrderId(dispatch.getOrderId());
            team.setDispatchId(dispatch.getId());
            team.setDeleteFlag(0);
            team.setSort(i);
            team.setCreateTime(new Date());
            List<OrderDispatchWorker> workers = team.getWorkers();
            // 工作班成员非必填，判空处理
            if(CollectionUtils.isNotEmpty(workers)) {
                Stream.iterate(0, j -> j + 1).limit(workers.size()).forEach(j -> {
                    OrderDispatchWorker worker = workers.get(j);
                    worker.setId(StringUtils.isBlank(worker.getId()) ? CodeTools.getCode32() : worker.getId());
                    worker.setOrderId(dispatch.getOrderId());
                    worker.setDispatchId(dispatch.getId());
                    worker.setTeamId(team.getId());
                    worker.setDeleteFlag(0);
                    worker.setSort(j);
                });
            }
            List<OrderWorkDeptPo> workerDept= team.getWorkerDept();
            if(CollectionUtils.isNotEmpty(workerDept)) {
                Stream.iterate(0, j -> j + 1).limit(workerDept.size()).forEach(j -> {
                    OrderWorkDeptPo dept = workerDept.get(j);
                    dept.setId(StringUtils.isBlank(dept.getId()) ? CodeTools.getCode32() : dept.getId());
                    dept.setOrderId(dispatch.getOrderId());
                    dept.setDispatchId(dispatch.getId());
                    dept.setTeamId(team.getId());
                    dept.setDeleteFlag(0);
                    dept.setSort(j);
                });
            }
        });
        // 此操作会先删除派工下的所有班组
        teamService.insertBatch(factory, convertor.teamVosToTeamBeans(teams));
        // 3、工作班成员（非必填）
        List<OrderDispatchWorker> workers = teams.stream()
                .filter(team -> CollectionUtils.isNotEmpty(team.getWorkers()))
                .flatMap(team -> team.getWorkers().stream())
                .collect(Collectors.toList());
        // 先删除派工下的所有班组成员
        workerService.deleteByOrderId(factory, dispatch.getOrderId());
        workerService.insertBatch(factory, workers);
        // 4、工作单位（非必填）
        List<OrderWorkDeptPo> workerDept = teams.stream()
                .filter(team -> CollectionUtils.isNotEmpty(team.getWorkerDept()))
                .flatMap(team -> team.getWorkerDept().stream())
                .collect(Collectors.toList());
        // 此操作会先删除派工下的所有的工作单位
        workDeptService.insertBatch(factory, workerDept);
        // 大修工单发送派工通知
        if (com.koron.common.core.util.StringUtils.isNotEmpty(dispatch.getTopicWorker())){
            String topicWorkerJson = dispatch.getTopicWorker();
            List<AppUserPo> userPoList = JSONUtil.parseArray(topicWorkerJson).toList(AppUserPo.class);
            String handler = userPoList.stream().map(AppUserPo::getAccount).collect(Collectors.joining(","));
            sendMessage(handler,dispatch,order);
        }
        return true;
    }

    private void sendMessage(String handler, OrderDispatch orderDispatch, OverhaulOrderBean orderBean) {
        String qywxHref = messageUtil.generateQywxHref("transmit_" + orderDispatch.getOrderType() + "_order", orderDispatch.getOrderId(),"","");
        messageUtil.sendMessageWithTemplate("dispatch_notice", qywxHref, handler, orderBean.getContext());
    }

    @Override
    public String getOrderId() {
        return "orderId";
    }

    @Override
    public int getOrder() {
        return 9001;
    }

    @Override
    public String status() {
        return Constants.OverhaulStatus.DISPATCHING;
    }
}
